﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Panopticon
{
    public class Actor
    {
        
        //Space and Movement
        public Rectangle space;
        protected Vector2 currentPosition;
        protected Vector2 lastPosition;
        protected Vector2 movement; //directly controlled by the actor
        public Vector2 momentum; //applied by outside forces, like gravity
        protected float moveSpeed;

        //Derived Dimentions
        public Vector2 nextPosition
        {
            get
            {
                return currentPosition + movement + momentum;
            }
        }
        public Rectangle nextSpace
        {
            get
            {
               return new Rectangle((int)nextPosition.X, (int)nextPosition.Y, space.Width, space.Height);
            }
        }
        public Vector2 nextYPos
        {
            get
            {
                Vector2 NYP = nextPosition;
                NYP.X = 0;
                return NYP;
            }
        }
        public Vector2 nextXPos
        {
            get
            {
                Vector2 NXP = nextPosition;
                NXP.Y = 0;
                return NXP;
            }
        }
        public Rectangle nextYSpace
        {
            get
            {
                return new Rectangle((int)currentPosition.X, (int)nextPosition.Y, space.Width, space.Height);
            }
        }
        public Rectangle nextXSpace
        {
            get
            {
                return new Rectangle((int)nextPosition.X, (int)currentPosition.Y, space.Width, space.Height);
            }
        }
        public Rectangle drawSpace
        {
            get
            {
                Rectangle db = new Rectangle(space.X-(int)World.relativeVector.X, space.Y-(int)World.relativeVector.Y, space.Width, space.Height);

                return db;

            }

        }
        
        
        //Graphics
        protected Texture2D texture;
        protected Color color;
        protected string title;

        //Physics
        public bool isSolid; //allows the actor to collide with other solid actors & determines if the actor can fall
        public bool isActive; //should I be checking you for collisions? 
        public bool isFalling; //determines if gravity is in effect
        public bool isStanding; //if im standing on a block
        

        public Actor(Rectangle mySpace, Texture2D myTexture, Color myColor)
        {
            space = mySpace;
            movement = Vector2.Zero;
            momentum = Vector2.Zero;
            moveSpeed = 0f;
            texture = myTexture;
            color = myColor;
            currentPosition = new Vector2(mySpace.X, mySpace.Y);

            isSolid = false;
            isActive = false;
            isFalling = true;
            isStanding = false;
        }

        public virtual void Update(GameTime gameTime)
        {
            //bool motionUnobstructed = true;
            bool xToZero = false;
            bool yToZero = false;

            //if i'm solid and active check for gravity and collisions
            if (isActive && isSolid)
            {
                if (World.Bounds.Bottom < nextSpace.Bottom || isStanding)
                {
                    isFalling = false;
                    momentum.Y = 0f;
                }
                else if (!isStanding)
                {
                    isFalling = true;
                    if (momentum.Y < World.terminalVelocity) // && Is.keyDown(Keys.T)
                        momentum += World.gravity;
                }

                isStanding = false;
                foreach (Actor otherActor in Game1.ActorList)
                {
                    if (!this.Equals(otherActor) && (otherActor.isSolid &&
                        nextSpace.Intersects(otherActor.space)))
                    {

                        if (Is.buttSpace(nextYSpace, 0).Intersects(Is.headSpace(otherActor.space, 1)) ||
                            Is.buttSpace(nextYSpace, 1).Intersects(Is.headSpace(otherActor.space, 0)))
                        {
                            isFalling = false;
                            isStanding = true;
                            yToZero = true;

                        }
                        if (Is.headSpace(nextYSpace, 0).Intersects(Is.buttSpace(otherActor.space, 1)) ||
                            Is.headSpace(nextYSpace, 1).Intersects(Is.buttSpace(otherActor.space, 0)))
                        {
                            yToZero = true;
                        }
                        if (Is.rightSpace(nextXSpace, 0).Intersects(Is.leftSpace(otherActor.space, 1)) ||
                            Is.rightSpace(nextXSpace, 1).Intersects(Is.leftSpace(otherActor.space, 0)))
                        {
                            xToZero = true;
                        }
                        if (Is.leftSpace(nextXSpace, 0).Intersects(Is.rightSpace(otherActor.space, 1)) ||
                            Is.leftSpace(nextXSpace, 1).Intersects(Is.rightSpace(otherActor.space, 0)))
                        { 
                            xToZero = true; 
                        }

                    }
                }
            }

            if (Is.rightSpace(nextXSpace, 0).Intersects(Is.rightSpace(World.Bounds, 1)) ||
                            Is.rightSpace(nextXSpace, 1).Intersects(Is.rightSpace(World.Bounds, 0)))
            {
                xToZero = true;
            }
            if (Is.leftSpace(nextXSpace, 0).Intersects(Is.leftSpace(World.Bounds, 1)) ||
                Is.leftSpace(nextXSpace, 1).Intersects(Is.leftSpace(World.Bounds, 0)))
            {
                xToZero = true;
            }

            if (xToZero)
            {
                momentum.X = 0f;
                movement.X = 0f;
            }
            if (yToZero)
            {
                momentum.Y = 0f;
                movement.Y = 0f;
            }

            if (World.Bounds.Contains(nextSpace))
            {
                lastPosition = currentPosition;
                currentPosition = nextPosition;
                space.X = (int)currentPosition.X;
                space.Y = (int)currentPosition.Y;
            }
        }


        public virtual void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, drawSpace, color);

            if (Globals.debugging)
            {
                spriteBatch.Draw(texture, Is.buttSpace(drawSpace, 1), Color.Red);
                spriteBatch.Draw(texture, Is.headSpace(drawSpace, 1), Color.Pink);
                spriteBatch.Draw(texture, Is.leftSpace(drawSpace, 1), Color.Purple);
                spriteBatch.Draw(texture, Is.rightSpace(drawSpace, 1), Color.SandyBrown);
            }
        }

    }
}
